package wsepForum.ui.jaxcent.states;

import java.util.Vector;

import jaxcent.HtmlDiv;
import jaxcent.HtmlElement;
import jaxcent.HtmlPara;
import jaxcent.JaxcentPage;
import jaxcent.Jaxception;
import wsepForum.common.elements.MessageHeader;
import wsepForum.common.elements.Section;
import wsepForum.common.elements.SectionHeader;
import wsepForum.common.elements.TopicHeader;
import wsepForum.common.elements.User.UserType;
import wsepForum.domain.handlers.MemberHandler;
import wsepForum.persistance.exceptions.WrongElementIDException;
import wsepForum.ui.jaxcent.IXContext;
import wsepForum.ui.jaxcent.states.XEditor.ActionType;

/**
 * @author Oren
 *
 */
public class XSection implements IXState {
	/*****************************
	 * MEMBERS                   *
	 *****************************/
	private IXContext context;
	private Section section;
	private HtmlElement xSectionTable;
	private HtmlElement xTopicsTable;
	private HtmlElement xSectionTitle;
	private HtmlElement xUserType;
	private HtmlDiv xPost;
	private HtmlDiv xSubSections;
	private HtmlDiv xSubTopics;
	private HtmlDiv xEditSection;
	private HtmlDiv xDropSection;
	private HtmlDiv xNewSection;
	private HtmlPara xNumUsers;
	private HtmlPara xUpSection;

	/*****************************
	 * CONSTRUCTOR               *
	 *****************************/
	private XSection(final IXContext context) {
		this.context = context;
		construct();
		JaxcentPage page = context.getPage();
		this.xUserType = new HtmlElement (page, "xusertype");
		this.xSectionTitle = new HtmlElement(page, "xtitle");
		this.xSectionTable = new HtmlElement(page, "xsections");
		this.xSubSections = new HtmlDiv(page, "xsubsections");
		this.xSubTopics = new HtmlDiv(page, "xsubtopics");
		this.xTopicsTable = new HtmlElement(page, "xtopics");
		this.xNumUsers = new HtmlPara(page,"xnumusers");
		initContent();
	}

	/*****************************
	 * METHODS                   *
	 *****************************/
	/**
	 * init button's actions
	 */
	private void initContent() {
		final JaxcentPage page = context.getPage();
		this.xUpSection = new HtmlPara(page,"xupsection") {
			public void onClick() {
				context.loadSection(section.getParentID());
			}
		};
		this.xPost = new HtmlDiv(page,"xpost1") {
			public void onClick() {
				context.loadEditor(ActionType.CREATE_NEW_TOPIC, new Object[] { section});
			}
		};

		this.xEditSection = new HtmlDiv(page,"xeditsection") {
			public void onClick() {
				context.loadSectionControl(section, false);
			}
		};
		this.xDropSection = new HtmlDiv(page,"xdropsection") {
			public void onClick() {
				try {
					boolean confirm = page.showConfirmDialog("Are you sure that you want to drop this section?");
					if (confirm) {
						section = context.getSession().getHandler().removeSection(section.getElementID());
						loadContent();
					}

				} catch (Jaxception e) {
					context.getPage().showMessageDialog("cannot comunnicate with page fields!");
					context.loadSection(0);
				}
				catch (Exception e) {
					page.showMessageDialog("Problem with section removal!\n"+e.getMessage());
				}
			}
		};
		this.xNewSection = new HtmlDiv(this.context.getPage(),"xnewsection") {
			public void onClick() {
				context.loadSectionControl(section, true);
			}
		};
	}

	public XSection(final IXContext context, int sectionId) {
		this(context);
		loadContent(sectionId);
	}

	public XSection(final IXContext context, Section section) {
		this(context);
		loadContent(section);
	}

	public boolean loadContent(int sectionId) {
		try {
			this.section = this.context.getSession().getHandler().getSection(sectionId);
		} catch (WrongElementIDException e1) {
			this.context.getPage().showMessageDialog("Section is not exist in the database, maybe deleted...");
			this.context.loadSection(0);
			return false;
		} catch (Exception e1) {
			this.context.getPage().showMessageDialog("Cannot load section! "+e1.getMessage());
			this.context.loadSection(0);
			return false;
		}
		loadContent();
		return true;
	}

	public void loadContent(Section section) {
		this.section = section;
		loadContent();
	}

	private void loadContent() {
		this.context.setSection(this.section.getElementID(),this.section.getHeadLine());
		try {
			if (this.section.getElementID() == 0) {
				this.xSectionTitle.setInnerHTML("Home");
				this.xUpSection.hide();
			}
			else {
				this.xSectionTitle.setInnerHTML(this.section.getHeadLine());
				this.xUpSection.show();
				//new HtmlAnchor(this.context.getPage(),"xupsectionlink").setHref("/?section."+section.getParentID());
			}
			int numberOfUsers = this.context.getSession().getHandler().getNumOfUsers();
			this.xNumUsers.setInnerHTML("There are <strong>"+String.valueOf(numberOfUsers)+"</strong> users connected right now.");
			setByUserType();
			Vector<SectionHeader> sections = this.section.getAllSectionHeaders();
			dealWithSubSections(sections);
			Vector<TopicHeader> topics = this.section.getAllTopicHeaders();
			dealWithSubTopics(topics);
		} catch (Jaxception e) {
			this.context.getPage().showMessageDialog("Failed to load page's content, please try reloading...\n"+e.getMessage());
		}

	}

	private void dealWithSubSections(Vector<SectionHeader> sections) throws Jaxception {
		if (sections.size()>0) {
			StringBuffer sectionsBuffer = new StringBuffer();
			for (SectionHeader s : sections) {
				sectionsBuffer.append(MakeSectionItem(s));
			}
			// put table on page
			this.xSectionTable.setInnerHTML(sectionsBuffer.toString());
			// link its links
			for (SectionHeader s : sections) {
				final int sid = s.getElementID();
				new HtmlElement(this.context.getPage(),"SEC"+s.getElementID()) {
					public void onClick() {
							loadContent(sid);
					}
				};
				TopicHeader lastTopic = s.getNewestTopic();
				if (lastTopic!=null) {
					final int tid = lastTopic.getElementID();
					new HtmlElement(this.context.getPage(),"TOH"+tid) {
						public void onClick() {
								context.loadTopic(tid,0);
						}
					};
				}
			}
			this.xSubSections.show();
		}
		else {
			this.xSubSections.hide();
			this.xSectionTable.setInnerHTML("");
		}
	}

	private void dealWithSubTopics(Vector<TopicHeader> topics) throws Jaxception{
		if (topics.size()>0) {
			StringBuffer topicsBuffer = new StringBuffer();
			int bgnum = 1;
			for (int i=0;i<topics.size();i++) {
				TopicHeader topic = topics.elementAt(i);
				topicsBuffer.append(makeTopicItem(bgnum,topic));
				bgnum = ((bgnum==1)?2:1);
			}
			// put table on page
			this.xTopicsTable.setInnerHTML(topicsBuffer.toString());
			// link its links
			for (TopicHeader t : topics) {
				final int tid = t.getElementID();
				new HtmlElement(this.context.getPage(),"TOP"+tid) {
					public void onClick() {
							context.loadTopic(tid,0);
					}
				};
				final MessageHeader mHeader = t.getNewestMessage();
				if (mHeader!=null) {
					new HtmlElement(this.context.getPage(),"MEH"+mHeader.getElementID()) {
						public void onClick() {
								context.loadTopic(tid,mHeader.getElementID());
						}
					};
				}
			}
			this.xSubTopics.show();
		}
		else {
			this.xSubTopics.hide();
			this.xTopicsTable.setInnerHTML("");
		}
	}

	private String MakeSectionItem(SectionHeader section) {
		String lastTopicStr,moderatorsList;
		TopicHeader lastTopic = section.getNewestTopic();
		if (lastTopic!=null) {
			lastTopicStr =
			"<a id=\"TOH"+lastTopic.getElementID()+"\">" +lastTopic.getHeadLine() +"</a>&nbsp;" +
			"<a href=\"/?topic."+lastTopic.getElementID()+"\"><img src=\"/images/icon_topic_latest.gif\" width=\"11\" height=\"9\" /></a>"+
			"<br />at "+lastTopic.getTimeStamp();
		} else {
			lastTopicStr = "";
		}
		Vector<String> moderators = section.getAllSectionMods();
		int modSize = moderators.size();
		if (modSize > 0) {
			moderatorsList = "Moderators: ";
			for (int i=0;i<modSize;i++) {
				if (i == (modSize-1))
					moderatorsList += "<a>"+moderators.elementAt(i)+"</a>";
				else
					moderatorsList += "<a>"+moderators.elementAt(i)+"</a>, ";
			}
		} else {
			moderatorsList = "";
		}
		return
		"<li class=\"row\">" +
		"<dl class=\"icon\" style=\"background-image: url(/images/forum_read.gif); background-repeat: no-repeat;\">" +
		"<dt title=\"Sections\">" +
		"<a class=\"forumtitle\" id=SEC"+section.getElementID()+">"+section.getHeadLine()+"</a>&nbsp;" +
		"<a href=\"/?section."+section.getElementID()+"\" ><img src=\"/images/icon_topic_latest.gif\" width=\"11\" height=\"9\" /></a>"+
		"<br />"+moderatorsList+"</dt>" +
		"<dd class=\"lastpost\"><span>" +
		"<dfn>Last Topic</dfn>"+lastTopicStr+"</span></dd></dl></li>";
	}

	private String makeTopicItem(int bgnum, TopicHeader topic) {
		MessageHeader msgHeader = topic.getNewestMessage();
		String messageStr;
		if (msgHeader!= null){
			String user = msgHeader.getUserName();
			if (user==null)
				user = "guest";
			messageStr =
			"<a id=\"MEH"+msgHeader.getElementID()+"\">"+ msgHeader.getHeadLine() +"</a>&nbsp;" +
			"<a href=\"/?topic."+topic.getElementID()+"."+ msgHeader.getElementID()+ "\"><img src=\"/images/icon_topic_latest.gif\" width=\"11\" height=\"9\" /></a>"+
			"<br />by <a>"+user+"</a>";
		} else
			messageStr = "";
		return
		"<li class=\"row bg"+ bgnum +"\">" +
		"<dl class=\"icon\" style=\"background-image: url(/images/topic_read.gif); background-repeat: no-repeat;\">" +
		"<dt title=\"Topic\">" +
		"<a id=TOP"+topic.getElementID()+" class=\"topictitle\">"+ topic.getHeadLine() +"</a>&nbsp;" +
		"<a href=\"/?topic."+topic.getElementID()+"\"><img src=\"/images/icon_topic_latest.gif\" width=\"11\" height=\"9\"></a>" +
		"<br />at "+ topic.getTimeStamp()+"</dt>"+
		"<dd class=\"lastpost\"><span><dfn>Last Message</dfn>" +
		messageStr+"</span></dd></dl></li>";
	}


	private void construct() {
		this.context.setBody(
		"<h2><a id=\"xtitle\"></a></h2>"+
		"<p style=\"display: none;\" id=\"xupsection\"><a id=\"xupsectionlink\" class=\"left-box right\" accesskey=\"r\">Up one section</a></p>&nbsp;<br />"+
		"<div id=\"xsubsections\" style=\"display: none;\" class=\"forabg\"><div class=\"inner\"><span class=\"corners-top\"><span></span></span>"+
		"<ul class=\"topiclist\"><li class=\"header\"><dl class=\"icon\">"+
		"<dt>Sections</dt>"+
		"<dd class=\"lastpost\"><span>Last Topic</span></dd>"+
		"</dl></li></ul><ul class=\"topiclist forums\" id=\"xsections\">"+
		"<br><br></ul><span class=\"corners-bottom\"><span></span></span></div>"+
		"</div><div class=\"topic-actions\"><div class=\"buttons\">"+
		"<div style=\"display: none;\" id=\"xpost1\" class=\"post-icon\"><a title=\"New topic\"><span></span>New Topic</a></div>"+
		"<div style=\"display: none;\" id=\"xnewsection\" class=\"newsection-icon\"><a title=\"New Section\"><span></span>New Section</a></div>"+
		"</div></div>"+
		"<div id=\"xsubtopics\" style=\"display: none;\" class=\"forumbg announcement\">"+
		"<div class=\"inner\"><span class=\"corners-top\"><span></span></span>"+
		"<ul class=\"topiclist\">"+
		"<li class=\"header\">"+
		"<dl class=\"icon\">"+
		"<dt>Topics</dt>"+
		"<dd class=\"lastpost\"><span>Last Message</span></dd>"+
		"</dl></li></ul>"+
		"<ul class=\"topiclist topics\" id=\"xtopics\">"+
		"<li class=\"row bg1\">"+
		"<br><br></li></ul>"+
		"<span class=\"corners-bottom\"><span></span></span></div></div>"+
		"<div class=\"topic-actions\">"+
		"<div class=\"buttons\">"+
		"<div style=\"display: none;\" id=\"xeditsection\" class=\"editsection-icon\"><a title=\"Edit Section\"><span></span>Edit Section</a></div>"+
		"<div style=\"display: none;\" id=\"xdropsection\" class=\"dropsection-icon\"><a title=\"Drop Section\"><span></span>Drop Section</a></div></div>"+
		"</div><p></p>"+
		"<h3>Forum users</h3>"+
		"<p id=\"xnumusers\"></p>"+
		"<h3>Permissions</h3>"+
		"<p id=\"xusertype\"></p>");
	}

	private void setByUserType() {
		UserType userType = context.getUserType();
		try {
			String userTypeStr = "You have <strong >"+userType.name().toLowerCase()+"</strong> level permissions on this forum.";


			if (userType != UserType.GUEST) {
				this.xPost.show();
				if (userType == UserType.ADMIN) {
					this.xEditSection.show();
					this.xNewSection.show();
					if (this.section.getElementID()!=0)this.xDropSection.show();
				}
				if (userType == UserType.MODERATOR) {
					Vector<Integer> sections = ((MemberHandler)this.context.getSession().getHandler()).getUser().getAllSections();
					if (sections.contains(new Integer(this.section.getElementID())))
						userTypeStr = userTypeStr + "<br />You have <strong >moderator</strong> level permissions on this section.";
					else
						userTypeStr = userTypeStr + "<br />You have <strong >member</strong> level permissions on this section.";
				}
			}
			else
			{
				this.xPost.hide();
				this.xDropSection.hide();
				this.xEditSection.hide();
				this.xNewSection.hide();
			}
			this.xUserType.setInnerHTML(userTypeStr );
		} catch (Jaxception e) {
			this.context.getPage().showMessageDialog("");
		}
	}


	@Override
	public StateType getType() {
		return StateType.SECTION;
	}

}
